package com.ycg.vue.modules.system.service.impl;

import com.ycg.vue.Entity.OperationLogEntity;
import com.ycg.vue.Entity.UserEntity;
import com.ycg.vue.Enum.LogEnum;
import com.ycg.vue.Enum.MinIOPathEnum;
import com.ycg.vue.Exception.CustomException;
import com.ycg.vue.constant.Constant;
import com.ycg.vue.constant.TableNameConstant;
import com.ycg.vue.context.ThreadLocalContext;
import com.ycg.vue.modules.system.Entity.BillTypeEntity;
import com.ycg.vue.modules.system.Dto.BillTypeDTO;
import com.ycg.vue.modules.system.mapper.BillMapper;
import com.ycg.vue.modules.system.mapper.SystemMapper;
import com.ycg.vue.modules.system.service.BillService;
import com.ycg.vue.modules.user.mapper.FileMapper;
import com.ycg.vue.modules.user.mapper.UserMapper;
import com.ycg.vue.result.Result;
import com.ycg.vue.utils.MinioUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Description
 * @Author jink
 * @Date 2024/6/13
 */
@Service
public class BillServiceImpl implements BillService {
    @Resource
    private BillMapper billMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private MinioUtils minioUtils;

    @Resource
    private FileMapper fileMapper;

    @Resource
    private SystemMapper systemMapper;

    @Override
    public Result billTypeList(BillTypeDTO billTypeDTO) {
        UserEntity user = userMapper.selectByUserId(ThreadLocalContext.getUserId());
        if (user == null) return Result.error(Constant.USER_STATUS_ERROR);
        List<BillTypeEntity> list = billMapper.TypeList(billTypeDTO);
        if (user.getIdentity() == 0) {
            list.stream().filter(x -> x.getExclusive() == 1).forEach(x -> {
                if (!x.getCreateBy().equals(user.getId())) list.remove(x);
            });
        }
        return Result.success(list);
    }

    @Override
    public Result uploadImg(MultipartFile file) {
        return Result.success(fileMapper.selectByGroupId(minioUtils.upload(file, MinIOPathEnum.BILL_ICON)));
    }

    @Override
    public Result InsertNewType(BillTypeDTO billTypeDTO) {
        try {
            UserEntity user = userMapper.selectByUserId(ThreadLocalContext.getUserId());
            if (user == null) return Result.error(Constant.USER_STATUS_ERROR);
            BillTypeEntity bill = new BillTypeEntity();
            BeanUtils.copyProperties(bill, billTypeDTO);
            if (user.getIdentity() == 0) bill.setExclusive((short) 1);
            else bill.setExclusive((short) 0);
            bill.setStatus((short) 1);
            billMapper.InsertNewType(bill);
            return Result.success();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(500, Constant.INSERT_ERROR);
        }
    }

    @Override
    public Result updateType(BillTypeDTO billTypeDTO) {
        BillTypeEntity bill = billMapper.selectById(billTypeDTO.getId());
        if (bill == null) return Result.error(Constant.BILL_TYPE_NOT_EXITS);
        try {
            String groupId = billTypeDTO.getGroupId().length() == 32 ? billTypeDTO.getGroupId() : bill.getGroupId();
            addLog(billTypeDTO, bill, true, "");
            billTypeDTO.setGroupId(groupId);
            billMapper.updateType(billTypeDTO);
            return Result.success();
        } catch (Exception e) {
            addLog(billTypeDTO, bill, false, e.getMessage());
            e.printStackTrace();
            throw new CustomException(500, Constant.UPDATE_ERROR);
        }
    }

    private void addLog(BillTypeDTO dto, BillTypeEntity bill, Boolean success, String msg) {
        StringBuilder sb = new StringBuilder();
        sb.append(bill.getId()).append("->");
        if (!dto.getName().equals(bill.getName()))
            sb.append(TableNameConstant.BILL_NAME).append(bill.getName()).append("-").append(dto.getName()).append("、");
        if (!dto.getType().equals(bill.getType()))
            sb.append(TableNameConstant.BILL_TYPE).append(bill.getType()).append("-").append(dto.getType()).append("、");
        if (!dto.getStatus().equals(bill.getStatus()))
            sb.append(TableNameConstant.BILL_STATUS).append(bill.getStatus()).append("-").append(dto.getStatus()).append("、");
        if (!dto.getExclusive().equals(bill.getExclusive()))
            sb.append(TableNameConstant.BILL_EXCLUSIVE).append(bill.getExclusive()).append("-").append(dto.getExclusive()).append("、");
        if (!dto.getGroupId().equals(bill.getGroupId()) && dto.getGroupId().length() == 32)
            sb.append(TableNameConstant.BILL_GROUP_ID).append(bill.getGroupId()).append("-").append(dto.getGroupId()).append("、");
        if (sb.length() >= 35) sb.deleteCharAt(sb.length() - 1);
        if (success)
            systemMapper.insertLog(OperationLogEntity.builder().type(LogEnum.UPDATE.getName()).operation(sb.toString()).success(true).build());
        else
            systemMapper.insertLog(OperationLogEntity.builder().type(LogEnum.UPDATE.getName()).operation(sb.toString()).success(false).message(msg).build());
    }

    @Override
    public Result deleteType(String id) {
        BillTypeEntity bill = billMapper.selectById(id);
        if (bill == null) return Result.error(Constant.BILL_TYPE_NOT_EXITS);
        billMapper.deleteById(id);
        systemMapper.insertLog(OperationLogEntity.builder().type(LogEnum.DELETE.getName()).operation(id + ":" + bill.getName()).success(true).build());
        return Result.success();
    }

}
